CDK destroyコマンドによる誤削除を防ぐ方法例
はじめに
こんにちは。アノテーションの及川です。
AWS のインフラ管理に CDK(Cloud Development Kit)を使用している開発者の皆さん、誤ってcdk destroy
コマンドを実行してしまい、重要なリソースが削除されるヒヤリハット経験はありませんか?
本記事では、そのような事故を防ぐための効果的な方法例を紹介します。
背景
開発環境で予期せぬ事態が発生したことがきっかけです。
開発者が誤ってcdk destroy
コマンドを CLI から実行し、開発環境の AWS リソースが大量に削除されてしまいました。
幸い、迅速な対応により環境は復旧しましたが、この経験から同様の事態を防ぐ仕組みの必要性を強く感じ、方法を検討しました。
解決策の検討
この問題に対処するため、CloudFormation を使用して、CDK の実行に関わる IAM ロールに対し、DeleteStack(API) の実行を明示的に拒否する仕組みを検討しました。
This IAM role grants permission to perform deployments into your environment. It is assumed by the CDK CLI during deployments.
By using a role for deployments, you can perform cross-account deployments since the role can be assumed by AWS identities in a different account.
このテンプレートは、CDK のデプロイロールに対して、すべてのリソースに対する DeleteStack の実行を拒否するポリシーを適用します。
CloudFormation テンプレート
以下が、実装したCloudFormation テンプレートの一例です。
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Attach deny delete stack policy to CDK deploy role'
Parameters:
Qualifier:
Type: String
Default: 'hnb659fds'
Description: 'The qualifier used in the CDK bootstrap process'
Resources:
DenyDeleteStackPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: !Sub 'deny-delete-stack-policy-${AWS::AccountId}-${AWS::Region}'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Deny
Action:
- cloudformation:DeleteStack
Resource: '*'
Roles:
- !Sub 'cdk-${Qualifier}-deploy-role-${AWS::AccountId}-${AWS::Region}'
Outputs:
DenyDeleteStackPolicyArn:
Description: ARN of the Deny Delete Stack Policy
Value: !Ref DenyDeleteStackPolicy
実際にやってみた
適当に AWS CDK のプロジェクトを作成して、cdk deploy
コマンドで AWS リソースをデプロイします。
% cdk deploy
✨ Synthesis time: 2.59s
StackDeletionPreventionTestStack: deploying... [1/1]
StackDeletionPreventionTestStack: creating CloudFormation changeset...
✅ StackDeletionPreventionTestStack (no changes)
✨ Deployment time: 1.65s
そして、前述の CloudFormation テンプレートを用いて、CDK のデプロイロールに対して、すべてのリソースに対する DeleteStack の実行を拒否するポリシーを適用します。
CloudFormation スタック作成
CDK のデプロイロールへ適用されている様子
cdk destroy コマンド実行(1回目)
想定したとおり、DeleteStack に対して、明示的な拒否(explicit deny)が適用されているため、cdk destroy
コマンドによるスタックの削除が許可されず失敗します。
% cdk destroy
Are you sure you want to delete: StackDeletionPreventionTestStack (y/n)? y
StackDeletionPreventionTestStack: destroying... [1/1]
❌ StackDeletionPreventionTestStack: destroy failed Error: User: arn:aws:sts::xxx:assumed-role/cdk-hnb659fds-deploy-role-xxx-ap-northeast-1/aws-cdk-xxx is not authorized to perform: cloudformation:DeleteStack on resource: arn:aws:cloudformation:ap-northeast-1:xxx:stack/StackDeletionPreventionTestStack/d2bcf110-74c2-11ef-bbeb-0e59ae201859 with an explicit deny in an identity-based policy
at destroyStack (/Users/xxx/dev/aws/awscdk/stack-deletion-prevention-test/node_modules/aws-cdk/lib/index.js:427:2204)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async CdkToolkit.destroy (/Users/xxx/dev/aws/awscdk/stack-deletion-prevention-test/node_modules/aws-cdk/lib/index.js:430:204806)
at async exec4 (/Users/xxx/dev/aws/awscdk/stack-deletion-prevention-test/node_modules/aws-cdk/lib/index.js:485:54250)
User: arn:aws:sts::xxx:assumed-role/cdk-hnb659fds-deploy-role-xxx-ap-northeast-1/aws-cdk-xxx is not authorized to perform: cloudformation:DeleteStack on resource: arn:aws:cloudformation:ap-northeast-1:xxx:stack/StackDeletionPreventionTestStack/d2bcf110-74c2-11ef-bbeb-0e59ae201859 with an explicit deny in an identity-based policy
cdk destroy コマンド実行(2回目)
DeleteStack の実行を明示的に拒否するポリシーの効果有無を確かめるため、こちらのポリシーを作成したスタックを削除した場合に、当該 CDK スタックがcdk destroy
より削除されるかについても検証してみました。
CDK のデプロイロールに対して、すべてのリソースに対する DeleteStack の実行を明示的に拒否するポリシーが適用されていないため、cdk destroy
コマンドは成功します。
% cdk destroy
Are you sure you want to delete: StackDeletionPreventionTestStack (y/n)? y
StackDeletionPreventionTestStack: destroying... [1/1]
✅ StackDeletionPreventionTestStack: destroyed
効果
この仕組みを用いることで、cdk destroy
コマンドの誤った実行による意図しないリソースの削除を防ぐことができます。
開発者は通常の CDK の操作(デプロイなど)を行えますが、cdk destroy
コマンドは拒否されるため、重大な事故を未然に防ぐことができます。
注意点
- この方法は開発環境や重要な本番環境に適していますが、頻繁にリソースの削除が必要な環境では不向きな場合があります。
- CDK の正常な操作に影響を与えないよう、適宜慎重にテストを行ってください。
- この仕組みは CDK CLI を通じた削除を防ぐものであり、CloudFormation コンソールや AWS CLI からの直接的なスタック削除は防げないことに注意してください。
まとめ
CDK destroy コマンドによる誤削除は、開発プロセスに大きな影響を与える可能性があります。
本記事で紹介した方法を行うことで、CDK destroy コマンドによる誤削除のリスクを大幅に軽減することが可能ですが、それぞれの AWS 環境の状況などにしたがって、適宜ご活用いただければ幸いです。
また、本記事以外にも本件に関連する弊社ブログもございますので、こちらも必要に応じてご参照いただき適宜お試しください。
この記事が誰かのお役に立てば幸いです。
アノテーション株式会社について
アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。
参考資料
- Protect CloudFormation stacks from being deleted - AWS CloudFormation
- Bootstrap your environment for use with the AWS CDK - AWS Cloud Development Kit (AWS CDK) v2
- Security And Safety Dev Guide · aws/aws-cdk Wiki
- aws-cdk/packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml at main · aws/aws-cdk
- AWS CDK でデプロイするときの最小権限について考えてみる | DevelopersIO
- CloudFormation Stackの削除を防止する機能についてまとめてみた | DevelopersIO
- 削除保護を設定したいCloudFormation StackをCDKで管理している場合の注意点 | DevelopersIO